package no.monsen.client.ui;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.TrayIcon.MessageType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.text.MessageFormat;

import no.monsen.client.common.MonsenClientConstants;
import no.monsen.client.common.factory.MonsenPropertiesFactory;
import no.monsen.client.controller.MonsenController;
import no.monsen.client.controller.MonsenObservable;
import no.monsen.monsenservice.MonsenFact;

public class MonsenSystrayUI implements MonsenDisplayElement, MonsenObserver {

	private MonsenFact message;
	private String severity = null;
	private TrayIcon trayIcon = null;
	private MonsenPropertiesFactory monsenPropFactory = null;
	private MonsenClipBoard monsenClipBoard = null;
	private MonsenController controller = null;

	public MonsenSystrayUI(MonsenObservable observable,
			final MonsenController controller) {
		// Make sure that the observer (this) is registered at the observable
		observable.registerObserver(this);
		this.controller = controller;

		// Need to get an instance of the property factory
		monsenPropFactory = MonsenPropertiesFactory.getInstance();

		// Need to identify is systray is supported
		if (SystemTray.isSupported()) {

			SystemTray tray = SystemTray.getSystemTray();
			URL pictureUrl = this.getClass().getResource(
					MonsenClientConstants.MONSEN_SYSTRAY_ICON);

			Image image = Toolkit.getDefaultToolkit().getImage(pictureUrl);

			PopupMenu popup = new PopupMenu();

			MenuItem updateItem = new MenuItem(monsenPropFactory
					.getProperty(MonsenClientConstants.MONSEN_LABEL_UPDATE));

			MenuItem helpItem = new MenuItem("Hjelp");

			MenuItem copyToClipboardItem = new MenuItem(monsenPropFactory
					.getProperty(MonsenClientConstants.MONSEN_LABEL_COPY));

			MenuItem exitItem = new MenuItem(monsenPropFactory
					.getProperty(MonsenClientConstants.MONSEN_LABEL_EXIT));

			MenuItem aboutItem = new MenuItem(monsenPropFactory
					.getProperty(MonsenClientConstants.MONSEN_LABEL_ABOUT));

			ActionListener copyFactListener = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (monsenClipBoard == null) {
						monsenClipBoard = new MonsenClipBoard();
					}
					monsenClipBoard.copyFactToClipBoard(message);
					trayIcon
							.displayMessage(
									monsenPropFactory
											.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_MESSAGE_CAPTION),
									monsenPropFactory
											.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_COPY_TO_CLIPBOARD),
									getMessageSeverity());
				}
			};

			ActionListener updateListener = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					
					Thread antiUIFreezeThread = new Thread(new Runnable() {
						public void run() {
							String clientVersion = monsenPropFactory.getProperty(MonsenClientConstants.MONSEN_CLIENT_VERSION);
							
							String displayMessage = controller.isUpdateAvailable(clientVersion);
							
							String captionTmp = monsenPropFactory.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_UPDATE_CAPTION);
							Object [] captionParams = {clientVersion};
							String captionMessage = MessageFormat.format(captionTmp, captionParams);
							
							trayIcon.displayMessage(captionMessage, displayMessage, getMessageSeverity() );
						}
					});
					//start the thread
					antiUIFreezeThread.start();
				}
			};

			ActionListener helpListener = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					trayIcon
							.displayMessage(
									monsenPropFactory
											.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_HELP_CAPTION),
									monsenPropFactory
											.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_HELP_MESSAGE),
									getMessageSeverity());
				}
			};

			ActionListener exitListener = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.exit(0);
				}
			};

			ActionListener aboutListener = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					String tmpCaptionMessage = monsenPropFactory.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_ABOUT_CAPTION) ;
					Object params [] = { monsenPropFactory.getProperty( MonsenClientConstants.MONSEN_CLIENT_VERSION ) };
					String captionMessage = MessageFormat.format(tmpCaptionMessage, params);
					trayIcon.displayMessage(captionMessage,
									monsenPropFactory
											.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_ABOUT_MESSAGE),
									getMessageSeverity());
				}
			};
			updateItem.addActionListener(updateListener);
			copyToClipboardItem.addActionListener(copyFactListener);
			helpItem.addActionListener(helpListener);
			exitItem.addActionListener(exitListener);
			aboutItem.addActionListener(aboutListener);
			popup.add(aboutItem);

			popup.addSeparator();
			popup.add(helpItem);
			popup.add(copyToClipboardItem);
			popup.addSeparator();
			popup.add(updateItem);
			popup.add(exitItem);

			trayIcon = new TrayIcon(
					image,
					monsenPropFactory
							.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_MESSAGE_CAPTION),
					popup);

			ActionListener actionListener = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					display();
				}
			};

			trayIcon.setImageAutoSize(true);
			trayIcon.addActionListener(actionListener);

			try {
				tray.add(trayIcon);
			} catch (AWTException e) {

			}
		}
	}

	public void update(MonsenFact message, String severity) {
		this.message = message;
		this.severity = severity;
		display();
	}

	public void display() {
		// need to check if message is null.
		if (message != null) {
			trayIcon
					.displayMessage(
							monsenPropFactory
									.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_MESSAGE_CAPTION),
							message.getFact(), getMessageSeverity());
		} else {
			// Probably some problems with service, a default local message is
			// displayed
			trayIcon
					.displayMessage(
							monsenPropFactory
									.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_MESSAGE_CAPTION),
							monsenPropFactory
									.getProperty(MonsenClientConstants.MONSEN_LABEL_SYSTRAY_DEFAULT_MESSAGE),
							getMessageSeverity());
		}

	}

	private MessageType getMessageSeverity() {
		if (severity != null) {
			if (severity.equalsIgnoreCase("info")) {
				return TrayIcon.MessageType.INFO;
			}
			if (severity.equalsIgnoreCase("warning")) {
				return TrayIcon.MessageType.WARNING;
			}
			if (severity.equalsIgnoreCase("error")) {
				return TrayIcon.MessageType.WARNING;
			}
		}
		return TrayIcon.MessageType.INFO;
	}
}
